# -*- indent-tabs-mode: nil; -*-
# vim: set sw=4 ts=8 et tw=78 ft=asm:
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is the TraceMonkey IMacro Assembler.
#
# The Initial Developer of the Original Code is
# Brendan Eich <brendan@mozilla.org>.
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****

.igroup equality JSOP_EQ-JSOP_NE

    .imacro any_obj                     # any obj
        dup                             # any obj obj
        dup                             # any obj obj obj
        getprop valueOf                 # any obj obj valueOf
        ifprimtop 1                     # any obj obj valueOf
        swap                            # any obj valueOf obj
        string void                     # any obj valueOf obj "void"
        call 1                          # any obj rval
        ifprimtop 3                     # any obj rval
        pop                             # any obj
        dup                             # any obj obj
        goto 2
1:      pop                             # any obj obj
2:      callprop toString               # any obj toString obj
        call 0                          # any obj rval
        primtop (JSTYPE_NUMBER)         # any obj rval
3:      swap                            # any rval obj
        pop                             # any rval
        imacop                          # eqval
        stop
    .end

    .imacro obj_any                     # obj any
        swap                            # any obj
        dup                             # any obj obj
        dup                             # any obj obj obj
        getprop valueOf                 # any obj obj valueOf
        ifprimtop 1                     # any obj obj valueOf
        swap                            # any obj valueOf obj
        string void                     # any obj valueOf obj "void"
        call 1                          # any obj lval
        ifprimtop 3                     # any obj lval
        pop                             # any obj
        dup                             # any obj obj
        goto 2
1:      pop                             # any obj obj
2:      callprop toString               # any obj toString obj
        call 0                          # any obj lval
        primtop (JSTYPE_NUMBER)         # any obj rval
3:      swap                            # any lval obj
        pop                             # any lval
        swap                            # lval any
        imacop                          # eqval
        stop
    .end

.end equality

# A single range, split up like so to test groups over multiple ranges of ops
.igroup binary JSOP_BITOR-JSOP_BITAND,JSOP_EQ-JSOP_DIV,JSOP_MOD

    .imacro any_obj                     # any obj
        dup                             # any obj obj
        dup                             # any obj obj obj
        getprop valueOf                 # any obj obj valueOf
        ifprimtop 1                     # any obj obj valueOf
        swap                            # any obj valueOf obj
        string number                   # any obj valueOf obj "number"
        call 1                          # any obj rval
        ifprimtop 3                     # any obj rval
        pop                             # any obj
        dup                             # any obj obj
        goto 2
1:      pop                             # any obj obj
2:      callprop toString               # any obj toString obj
        call 0                          # any obj rval
        primtop (JSTYPE_NUMBER)         # any obj rval
3:      swap                            # any rval obj
        pop                             # any rval
        imacop                          # bval
        stop
    .end

    .imacro obj_any                     # obj any
        swap                            # any obj
        dup                             # any obj obj
        dup                             # any obj obj obj
        getprop valueOf                 # any obj obj valueOf
        ifprimtop 1                     # any obj obj valueOf
        swap                            # any obj valueOf obj
        string number                   # any obj valueOf obj "number"
        call 1                          # any obj lval
        ifprimtop 3                     # any obj lval
        pop                             # any obj
        dup                             # any obj obj
        goto 2
1:      pop                             # any obj obj
2:      callprop toString               # any obj toString obj
        call 0                          # any obj lval
        primtop (JSTYPE_NUMBER)         # any obj lval
3:      swap                            # any lval obj
        pop                             # any lval
        swap                            # lval any
        imacop                          # bval
        stop
    .end

    .imacro obj_obj                     # obj1 obj2
        swap                            # obj2 obj1
        dup                             # obj2 obj1 obj1
        dup                             # obj2 obj1 obj1 obj1
        getprop valueOf                 # obj2 obj1 obj1 valueOf
        ifprimtop 1                     # obj2 obj1 obj1 valueOf
        swap                            # obj2 obj1 valueOf obj1
        string number                   # obj2 obj1 valueOf obj1 "number"
        call 1                          # obj2 obj1 lval
        ifprimtop 3                     # obj2 obj1 lval
        pop                             # obj2 obj1
        dup                             # obj2 obj1 obj1
        goto 2
1:      pop                             # obj2 obj1 obj1
2:      callprop toString               # obj2 obj1 toString obj1
        call 0                          # obj2 obj1 lval
        primtop (JSTYPE_NUMBER)         # obj2 obj1 lval
3:      swap                            # obj2 lval obj1
        pop                             # obj2 lval
        swap                            # lval obj2
        dup                             # lval obj1 obj1
        dup                             # lval obj obj obj
        getprop valueOf                 # lval obj obj valueOf
        ifprimtop 4                     # lval obj obj valueOf
        swap                            # lval obj valueOf obj
        string number                   # lval obj valueOf obj "number"
        call 1                          # lval obj rval
        ifprimtop 6                     # lval obj rval
        pop                             # lval obj
        dup                             # lval obj obj
        goto 5
4:      pop                             # lval obj obj
5:      callprop toString               # lval obj toString obj
        call 0                          # lval obj rval
        primtop (JSTYPE_NUMBER)         # lval obj rval
6:      swap                            # lval rval obj
        pop                             # lval rval
        imacop                          # bval
        stop
    .end

.end binary

.igroup add JSOP_ADD

    .imacro any_obj                     # any obj
        dup                             # any obj obj
        dup                             # any obj obj obj
        getprop valueOf                 # any obj obj valueOf
        ifprimtop 1                     # any obj obj valueOf
        swap                            # any obj valueOf obj
        string void                     # any obj valueOf obj "void"
        call 1                          # any obj rval
        ifprimtop 3                     # any obj rval
        pop                             # any obj
        dup                             # any obj obj
        goto 2
1:      pop                             # any obj obj
2:      callprop toString               # any obj toString obj
        call 0                          # any obj rval
        primtop (JSTYPE_VOID)           # any obj rval
3:      swap                            # any rval obj
        pop                             # any rval
        add                             # aval
        stop
    .end

    .imacro obj_any                     # obj any
        swap                            # any obj
        dup                             # any obj obj
        dup                             # any obj obj obj
        getprop valueOf                 # any obj obj valueOf
        ifprimtop 1                     # any obj obj valueOf
        swap                            # any obj valueOf obj
        string void                     # any obj valueOf obj "void"
        call 1                          # any obj lval
        ifprimtop 3                     # any obj lval
        pop                             # any obj
        dup                             # any obj obj
        goto 2
1:      pop                             # any obj obj
2:      callprop toString               # any obj toString obj
        call 0                          # any obj lval
        primtop (JSTYPE_VOID)           # any obj lval
3:      swap                            # any lval obj
        pop                             # any lval
        swap                            # lval any
        add                             # aval
        stop
    .end

    .imacro obj_obj                     # obj1 obj2
        swap                            # obj2 obj1
        dup                             # obj2 obj1 obj1
        dup                             # obj2 obj1 obj1 obj1
        getprop valueOf                 # obj2 obj1 obj1 valueOf
        ifprimtop 1                     # obj2 obj1 obj1 valueOf
        swap                            # obj2 obj1 valueOf obj1
        string void                     # obj2 obj1 valueOf obj1 "void"
        call 1                          # obj2 obj1 lval
        ifprimtop 3                     # obj2 obj1 lval
        pop                             # obj2 obj1
        dup                             # obj2 obj1 obj1
        goto 2
1:      pop                             # obj2 obj1 obj1
2:      callprop toString               # obj2 obj1 toString obj1
        call 0                          # obj2 obj1 lval
        primtop (JSTYPE_VOID)           # obj2 obj1 lval
3:      swap                            # obj2 lval obj1
        pop                             # obj2 lval
        swap                            # lval obj2
        dup                             # lval obj obj
        dup                             # lval obj obj obj
        getprop valueOf                 # lval obj obj valueOf
        ifprimtop 4                     # lval obj obj valueOf
        swap                            # lval obj valueOf obj
        string void                     # lval obj valueOf obj "void"
        call 1                          # lval obj rval
        ifprimtop 6                     # lval obj rval
        pop                             # lval obj
        dup                             # lval obj obj
        goto 5
4:      pop                             # lval obj obj
5:      callprop toString               # lval obj toString obj
        call 0                          # lval obj rval
        primtop (JSTYPE_VOID)           # lval obj rval
6:      swap                            # lval rval obj
        pop                             # lval rval
        add                             # aval
        stop
    .end

.end add

.igroup unary JSOP_NEG-JSOP_POS

    .imacro sign                        # obj
        dup                             # obj obj
        dup                             # obj obj obj
        getprop valueOf                 # obj obj valueOf
        ifprimtop 2                     # obj obj valueOf
        swap                            # obj valueOf obj
        string number                   # obj valueOf obj "number"
        call 1                          # obj lval
        ifprimtop 1                     # obj lval
        pop                             # obj
        dup                             # obj obj
        goto 3
1:      swap                            # lval obj
        pop                             # lval
        goto 4
2:      pop                             # obj obj
3:      callprop toString               # obj toString obj
        call 0                          # obj lval
        primtop (JSTYPE_NUMBER)         # obj lval
        swap                            # lval obj
        pop                             # lval
4:      imacop                          # aval
        stop
    .end

.end unary

.igroup incelem JSOP_INCELEM,JSOP_ELEMINC
    .imacro incelem                     # obj id
        dup2                            # obj id obj id
        getelem                         # obj id val
        pos                             # obj id n
        one                             # obj id n 1
        add                             # obj id m
        setelem                         # m
        stop
    .end

    .imacro eleminc                     # obj id
        dup2                            # obj id obj id
        getelem                         # obj id val
        pos                             # obj id n
        dup                             # obj id n n
        one                             # obj id n n 1
        add                             # obj id n m
        pick 3                          # id n m obj
        pick 3                          # n m obj id
        pick 2                          # n obj id m
        setelem                         # n m
        pop                             # n
        stop
    .end
.end incelem

.igroup decelem JSOP_DECELEM,JSOP_ELEMDEC
    .imacro decelem                     # obj id
        dup2                            # obj id obj id
        getelem                         # obj id val
        pos                             # obj id n
        one                             # obj id n 1
        sub                             # obj id m
        setelem                         # m
        stop
    .end

    .imacro elemdec                     # obj id
        dup2                            # obj id obj id
        getelem                         # obj id val
        pos                             # obj id n
        dup                             # obj id n n
        one                             # obj id n n 1
        sub                             # obj id n m
        pick 3                          # id n m obj
        pick 3                          # n m obj id
        pick 2                          # n obj id m
        setelem                         # n m
        pop                             # n
        stop
    .end
.end decelem

.igroup call JSOP_CALL

    .imacro String                          # String this obj
        dup                                 # String this obj obj
        dup                                 # String this obj obj obj
        getprop toString                    # String this obj obj toString
        ifprimtop 1                         # String this obj obj toString
        swap                                # String this obj toString obj
        call 0                              # String this obj rval
        ifprimtop 3                         # String this obj rval
        pop                                 # String this obj
        dup                                 # String this obj obj
        goto 2
1:      pop                                 # String this obj obj
2:      callprop valueOf                    # String this obj valueOf obj
        string string                       # String this obj valueOf obj "string"
        call 1                              # String this obj rval
        primtop (JSTYPE_STRING)             # String this obj rval
3:      swap                                # String this rval obj
        pop                                 # String this rval
        call 1                              # str
        stop                                # str
    .end

.end call

.igroup new JSOP_NEW

    .imacro String                          # String this obj
        dup                                 # String this obj obj
        dup                                 # String this obj obj obj
        getprop toString                    # String this obj obj toString
        ifprimtop 1                         # String this obj obj toString
        swap                                # String this obj toString obj
        call 0                              # String this obj rval
        ifprimtop 3                         # String this obj rval
        pop                                 # String this obj
        dup                                 # String this obj obj
        goto 2
1:      pop                                 # String this obj obj
2:      callprop valueOf                    # String this obj valueOf obj
        string string                       # String this obj valueOf obj "string"
        call 1                              # String this obj rval
        primtop (JSTYPE_STRING)             # String this obj rval
3:      swap                                # String this rval obj
        pop                                 # String this rval
        new 1                               # strobj
        stop                                # strobj
    .end

.end new

.igroup apply JSOP_APPLY

    .imacro apply0                          # apply fun this arr
        pick 3                              # fun this arr apply
        pop                                 # fun this arr
        pop                                 # fun this
        call 0                              #
        stop                                #
    .end                                    #

    .imacro apply1                          # apply fun this arr
        pick 3                              # fun this arr apply
        pop                                 # fun this arr
        dup                                 # fun this arr arr
        zero                                # fun this arr arr 0
        getelem                             # fun this arr arg0
        swap                                # fun this arg0 arr
        pop                                 # fun this arg0
        call 1                              #
        stop                                #
    .end                                    #

    .imacro apply2                          # apply fun this arr
        pick 3                              # fun this arr apply
        pop                                 # fun this arr
        dup                                 # fun this arr arr
        zero                                # fun this arr arr 0
        getelem                             # fun this arr arg0
        swap                                # fun this arg0 arr
        dup                                 # fun this arg0 arr arr
        one                                 # fun this arg0 arr arr 1
        getelem                             # fun this arg0 arr arg1
        swap                                # fun this arg0 arg1 arr
        pop                                 # fun this arg0 arg1
        call 2                              #
        stop                                #
    .end                                    #

    .imacro apply3                          # apply fun this arr
        pick 3                              # fun this arr apply
        pop                                 # fun this arr
        dup                                 # fun this arr arr
        zero                                # fun this arr arr 0
        getelem                             # fun this arr arg0
        swap                                # fun this arg0 arr
        dup                                 # fun this arg0 arr arr
        one                                 # fun this arg0 arr arr 1
        getelem                             # fun this arg0 arr arg1
        swap                                # fun this arg0 arg1 arr
        dup                                 # fun this arg0 arg1 arr arr
        int8 2                              # fun this arg0 arg1 arr arr 2
        getelem                             # fun this arg0 arg1 arr arg2
        swap                                # fun this arg0 arg1 arg2 arr
        pop                                 # fun this arg0 arg1 arg2
        call 3                              #
        stop                                #
    .end                                    #

    .imacro apply4                          # apply fun this arr
        pick 3                              # fun this arr apply
        pop                                 # fun this arr
        dup                                 # fun this arr arr
        zero                                # fun this arr arr 0
        getelem                             # fun this arr arg0
        swap                                # fun this arg0 arr
        dup                                 # fun this arg0 arr arr
        one                                 # fun this arg0 arr arr 1
        getelem                             # fun this arg0 arr arg1
        swap                                # fun this arg0 arg1 arr
        dup                                 # fun this arg0 arg1 arr arr
        int8 2                              # fun this arg0 arg1 arr arr 2
        getelem                             # fun this arg0 arg1 arr arg2
        swap                                # fun this arg0 arg1 arg2 arr
        dup                                 # fun this arg0 arg1 arg2 arr arr
        int8 3                              # fun this arg0 arg1 arg2 arr arr 3
        getelem                             # fun this arg0 arg1 arg2 arr arg3
        swap                                # fun this arg0 arg1 arg2 arg3 arr
        pop                                 # fun this arg0 arg1 arg2 arg3
        call 4                              #
        stop                                #
    .end                                    #

    .imacro apply5                          # apply fun this arr
        pick 3                              # fun this arr apply
        pop                                 # fun this arr
        dup                                 # fun this arr arr
        zero                                # fun this arr arr 0
        getelem                             # fun this arr arg0
        swap                                # fun this arg0 arr
        dup                                 # fun this arg0 arr arr
        one                                 # fun this arg0 arr arr 1
        getelem                             # fun this arg0 arr arg1
        swap                                # fun this arg0 arg1 arr
        dup                                 # fun this arg0 arg1 arr arr
        int8 2                              # fun this arg0 arg1 arr arr 2
        getelem                             # fun this arg0 arg1 arr arg2
        swap                                # fun this arg0 arg1 arg2 arr
        dup                                 # fun this arg0 arg1 arg2 arr arr
        int8 3                              # fun this arg0 arg1 arg2 arr arr 3
        getelem                             # fun this arg0 arg1 arg2 arr arg3
        swap                                # fun this arg0 arg1 arg2 arg3 arr
        dup                                 # fun this arg0 arg1 arg2 arg3 arr arr
        int8 4                              # fun this arg0 arg1 arg2 arg3 arr arr 4
        getelem                             # fun this arg0 arg1 arg2 arg3 arr arg4
        swap                                # fun this arg0 arg1 arg2 arg3 arg4 arr
        pop                                 # fun this arg0 arg1 arg2 arg3 arg4
        call 5                              #
        stop                                #
    .end                                    #

    .imacro apply6                          # apply fun this arr
        pick 3                              # fun this arr apply
        pop                                 # fun this arr
        dup                                 # fun this arr arr
        zero                                # fun this arr arr 0
        getelem                             # fun this arr arg0
        swap                                # fun this arg0 arr
        dup                                 # fun this arg0 arr arr
        one                                 # fun this arg0 arr arr 1
        getelem                             # fun this arg0 arr arg1
        swap                                # fun this arg0 arg1 arr
        dup                                 # fun this arg0 arg1 arr arr
        int8 2                              # fun this arg0 arg1 arr arr 2
        getelem                             # fun this arg0 arg1 arr arg2
        swap                                # fun this arg0 arg1 arg2 arr
        dup                                 # fun this arg0 arg1 arg2 arr arr
        int8 3                              # fun this arg0 arg1 arg2 arr arr 3
        getelem                             # fun this arg0 arg1 arg2 arr arg3
        swap                                # fun this arg0 arg1 arg2 arg3 arr
        dup                                 # fun this arg0 arg1 arg2 arg3 arr arr
        int8 4                              # fun this arg0 arg1 arg2 arg3 arr arr 4
        getelem                             # fun this arg0 arg1 arg2 arg3 arr arg4
        swap                                # fun this arg0 arg1 arg2 arg3 arg4 arr
        dup                                 # fun this arg0 arg1 arg2 arg3 arg4 arr arr
        int8 5                              # fun this arg0 arg1 arg2 arg3 arg4 arr arr 5
        getelem                             # fun this arg0 arg1 arg2 arg3 arg4 arr arg5
        swap                                # fun this arg0 arg1 arg2 arg3 arg4 arg5 arr
        pop                                 # fun this arg0 arg1 arg2 arg3 arg4 arg5
        call 6                              #
        stop                                #
    .end                                    #

    .imacro apply7                          # apply fun this arr
        pick 3                              # fun this arr apply
        pop                                 # fun this arr
        dup                                 # fun this arr arr
        zero                                # fun this arr arr 0
        getelem                             # fun this arr arg0
        swap                                # fun this arg0 arr
        dup                                 # fun this arg0 arr arr
        one                                 # fun this arg0 arr arr 1
        getelem                             # fun this arg0 arr arg1
        swap                                # fun this arg0 arg1 arr
        dup                                 # fun this arg0 arg1 arr arr
        int8 2                              # fun this arg0 arg1 arr arr 2
        getelem                             # fun this arg0 arg1 arr arg2
        swap                                # fun this arg0 arg1 arg2 arr
        dup                                 # fun this arg0 arg1 arg2 arr arr
        int8 3                              # fun this arg0 arg1 arg2 arr arr 3
        getelem                             # fun this arg0 arg1 arg2 arr arg3
        swap                                # fun this arg0 arg1 arg2 arg3 arr
        dup                                 # fun this arg0 arg1 arg2 arg3 arr arr
        int8 4                              # fun this arg0 arg1 arg2 arg3 arr arr 4
        getelem                             # fun this arg0 arg1 arg2 arg3 arr arg4
        swap                                # fun this arg0 arg1 arg2 arg3 arg4 arr
        dup                                 # fun this arg0 arg1 arg2 arg3 arg4 arr arr
        int8 5                              # fun this arg0 arg1 arg2 arg3 arg4 arr arr 5
        getelem                             # fun this arg0 arg1 arg2 arg3 arg4 arr arg5
        swap                                # fun this arg0 arg1 arg2 arg3 arg4 arg5 arr
        dup                                 # fun this arg0 arg1 arg2 arg3 arg4 arg5 arr arr
        int8 6                              # fun this arg0 arg1 arg2 arg3 arg4 arg5 arr arr 6
        getelem                             # fun this arg0 arg1 arg2 arg3 arg4 arg5 arr arg6
        swap                                # fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6 arr
        pop                                 # fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6
        call 7                              #
        stop                                #
    .end                                    #

    .imacro apply8                          # apply fun this arr
        pick 3                              # fun this arr apply
        pop                                 # fun this arr
        dup                                 # fun this arr arr
        zero                                # fun this arr arr 0
        getelem                             # fun this arr arg0
        swap                                # fun this arg0 arr
        dup                                 # fun this arg0 arr arr
        one                                 # fun this arg0 arr arr 1
        getelem                             # fun this arg0 arr arg1
        swap                                # fun this arg0 arg1 arr
        dup                                 # fun this arg0 arg1 arr arr
        int8 2                              # fun this arg0 arg1 arr arr 2
        getelem                             # fun this arg0 arg1 arr arg2
        swap                                # fun this arg0 arg1 arg2 arr
        dup                                 # fun this arg0 arg1 arg2 arr arr
        int8 3                              # fun this arg0 arg1 arg2 arr arr 3
        getelem                             # fun this arg0 arg1 arg2 arr arg3
        swap                                # fun this arg0 arg1 arg2 arg3 arr
        dup                                 # fun this arg0 arg1 arg2 arg3 arr arr
        int8 4                              # fun this arg0 arg1 arg2 arg3 arr arr 4
        getelem                             # fun this arg0 arg1 arg2 arg3 arr arg4
        swap                                # fun this arg0 arg1 arg2 arg3 arg4 arr
        dup                                 # fun this arg0 arg1 arg2 arg3 arg4 arr arr
        int8 5                              # fun this arg0 arg1 arg2 arg3 arg4 arr arr 5
        getelem                             # fun this arg0 arg1 arg2 arg3 arg4 arr arg5
        swap                                # fun this arg0 arg1 arg2 arg3 arg4 arg5 arr
        dup                                 # fun this arg0 arg1 arg2 arg3 arg4 arg5 arr arr
        int8 6                              # fun this arg0 arg1 arg2 arg3 arg4 arg5 arr arr 6
        getelem                             # fun this arg0 arg1 arg2 arg3 arg4 arg5 arr arg6
        swap                                # fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6 arr
        dup                                 # fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6 arr arr
        int8 7                              # fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6 arr arr 7
        getelem                             # fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6 arr arg7
        swap                                # fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arr
        pop                                 # fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6 arg7
        call 8                              #
        stop                                #
    .end                                    #

    .imacro call0                           # call fun
        swap                                # fun call
        pop                                 # fun
        null                                # fun this
        call 0                              #
        stop                                #
    .end                                    #

    .imacro call1                           # call fun this
        pick 2                              # fun this call
        pop                                 # fun this
        call 0                              #
        stop                                #
    .end                                    #

    .imacro call2                           # call fun this arg0
        pick 3                              # fun this arg0 call
        pop                                 # fun this arg0
        call 1                              #
        stop                                #
    .end                                    #

    .imacro call3                           # call fun this arg0 arg1
        pick 4                              # fun this arg0 arg1 call
        pop                                 # fun this arg0 arg1
        call 2                              #
        stop                                #
    .end                                    #

    .imacro call4                           # call fun this arg0 arg1 arg2
        pick 5                              # fun this arg0 arg1 arg2 call
        pop                                 # fun this arg0 arg1 arg2
        call 3                              #
        stop                                #
    .end                                    #

    .imacro call5                           # call fun this arg0 arg1 arg2 arg3
        pick 6                              # fun this arg0 arg1 arg2 arg3 call
        pop                                 # fun this arg0 arg1 arg2 arg3
        call 4                              #
        stop                                #
    .end                                    #

    .imacro call6                           # call fun this arg0 arg1 arg2 arg3 arg4
        pick 7                              # fun this arg0 arg1 arg2 arg3 arg4 call
        pop                                 # fun this arg0 arg1 arg2 arg3 arg4
        call 5                              #
        stop                                #
    .end                                    #

    .imacro call7                           # call fun this arg0 arg1 arg2 arg3 arg4 arg5
        pick 8                              # fun this arg0 arg1 arg2 arg3 arg4 arg5 call
        pop                                 # fun this arg0 arg1 arg2 arg3 arg4 arg5
        call 6                              #
        stop                                #
    .end                                    #

    .imacro call8                           # call fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6
        pick 9                              # fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6 call
        pop                                 # fun this arg0 arg1 arg2 arg3 arg4 arg5 arg6
        call 7                              #
        stop                                #
    .end                                    #

.end apply

.igroup getprop JSOP_GETPROP
    .imacro scriptgetter        # obj
        .fixup +1               # getter obj
        call 0                  # val
        stop
    .end
.end getprop

.igroup callprop JSOP_CALLPROP
    .imacro scriptgetter        # obj
        .fixup +2               # obj getter obj
        call 0                  # obj method
        swap                    # method obj
        stop
    .end
.end callprop

.igroup getthisprop JSOP_GETTHISPROP,JSOP_GETARGPROP,JSOP_GETLOCALPROP
    .imacro scriptgetter        #
        .fixup +2               # getter obj
        call 0                  # val
        stop
    .end
.end getthisprop
